/*
 * This file (AxActor.java) is protected by the GNU GPL licence (v2). 
 * Please read the license.txt attached for further informations. 
 * 
 */

package artx.objects;

import artx.utils.AxLog;

/**
 * Basic Actor, able to manipulate other objects.
 * 
 * @author Xavier Gouchet
 * 
 */
public abstract class AxActor extends AxObject implements Runnable {

	/** Actor's author name or alias. */
	protected String author;

	/** Actor's description. */
	protected String description;

	// TODO add AxActorEvents and AkActorListeners

	/**
	 * Standard constructor.
	 * 
	 * @param name
	 *            the actor's name
	 * @param auth
	 *            the actor's author
	 * @param desc
	 *            the actor's description
	 */
	public AxActor(String name, String auth, String desc) {
		super(-1, name);
		if (auth != null)
			this.author = new String(auth);
		if (desc != null)
			this.description = new String(desc);
	}

	/**
	 * Awakes the actor (mainly sets is mood and (re)start new artspace).
	 * 
	 */
	protected abstract void Awake();

	/**
	 * Put the actor too sleep (mainly save his mood and artspaces).
	 * 
	 */
	protected abstract void Sleep();

	/**
	 * Make the actor work on one or multiple artspaces. This method is called
	 * multiple times, so the content of this method should be minimal.
	 * 
	 * @return boolean whether the actor has finished working
	 */
	protected abstract boolean Work();

	/**
	 * @see java.lang.Runnable#run()
	 */
	public final void run() {
		// first awake the actor
		AxLog.Debug("AxActor::run =>> Awake the actor [" + this.NAME + "]");
		this.Awake();

		// then work
		boolean work = true;
		while (work) {
			AxLog.Debug("AxActor::run =>> working loop [" + this.NAME + "]");
			work = this.Work();
			// DISCUSS add a fake thinking delay for each loop?
		}

		// finally put the actor to sleep
		AxLog.Debug("AxActor::run =>> put the actor to sleep [" + this.NAME
				+ "]");
		this.Sleep();
	}

	/**
	 * @see artx.objects.AxObject#toString()
	 */
	public final String toString() {
		return "Actor \"" + this.NAME + "\" created by " + this.author + " ("
				+ this.description + ")";
	}

	/**
	 * @return the actor's author
	 */
	public final String GetAuthor() {
		if (this.author == null)
			return "?";
		return new String(this.author);
	}

	/**
	 * @return the actor's descrition
	 */
	public final String GetDescription() {
		if (this.description == null)
			return "...";
		return new String(this.description);
	}
}
